package cn.psvmc.cxzapi.service.customer;

import cn.psvmc.cxzapi.exception.ServiceException;
import cn.psvmc.cxzapi.mapper.customer.TCustomerMapper;
import cn.psvmc.cxzapi.mapper.goods.TGoodsMapper;
import cn.psvmc.cxzapi.mapper.goods.TGoodsSpecsMapper;
import cn.psvmc.cxzapi.mapper.order.*;
import cn.psvmc.cxzapi.mapper.system.TPlatformSetMapper;
import cn.psvmc.cxzapi.model.common.OrderBillEntity;
import cn.psvmc.cxzapi.model.common.OrderEntity;
import cn.psvmc.cxzapi.model.customer.TCustomer;
import cn.psvmc.cxzapi.model.customer.TCustomerAuth;
import cn.psvmc.cxzapi.model.order.*;
import cn.psvmc.cxzapi.service.alipay.AlipayCreate;
import cn.psvmc.cxzapi.service.order.TOrderLogService;
import cn.psvmc.cxzapi.service.system.ServiceUtil;
import cn.psvmc.cxzapi.util.CodeUtil;
import cn.psvmc.cxzapi.util.ToolUtils;
import com.alipay.api.domain.GoodsDetail;
import com.alipay.api.response.AlipayOpenMiniOrderInstallmentCreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.istack.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author ywx
 * @className TCustomerOrderService
 * @description
 * @date 2024/9/3 22:18
 **/
@Service
public class TCustomerOrderService {
    @Resource
    private TOrderMapper orderMapper;
    @Resource
    private ServiceUtil serviceUtil;
    @Resource
    private TOrderBillMapper tOrderBillMapper;
    @Resource
    private TGoodsSpecsMapper goodsSpecsMapper;
    @Resource
    private TOrderLogService orderLogService;
    @Resource
    private TPlatformSetMapper platformSetMapper;
    @Resource
    private TGoodsMapper goodsMapper;
    @Resource
    private TOrderDeliveryMapper orderDeliveryMapper;
    @Resource
    private TOrderContractMapper orderContractMapper;
    @Resource
    private TCustomerMapper customerMapper;
    //读写锁（多个线程可以同时持有读锁，但只能有一个线程持有写锁。适用于读多写少的场景）
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();

    /**
     * @Description 订单列表
     * @Date 2024/8/27 22:40
     * @Author YWX
     * @Param [queryPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map < java.lang.String, java.lang.Object>>
     **/
    public IPage<Map<String, Object>> listOrder(Page<TOrder> queryPage, OrderEntity entity) {
        entity.setCustomerid(serviceUtil.getCustomerId());
        int customerAuth = serviceUtil.getCustomerAuth(entity.getCustomerid());

        IPage<Map<String, Object>> mapIPage = orderMapper.listMyOrder(queryPage, entity);
        mapIPage.getRecords().forEach(order -> order.put("customerAuth", customerAuth));
        return mapIPage;
    }

    /**
     * @Description 买断申请
     * @Date 2024/8/27 9:50
     * @Author YWX
     * @Param [orderId]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void addBuyout(Integer orderId) {
        TOrder order = checkOrder(orderId);
        if (order.getOrderType().equals(2)) {
            throw new ServiceException("此订单为买断订单，不能再次添加！");
        }
        Integer type = goodsSpecsMapper.getTypeById(order.getGsid());//根据商品规格id获取租赁方案
        if (type == null || !type.equals(2)) {
            throw new ServiceException("此商品不支持买断！");
        }
        // 新生成订单
        TOrder buyoutOrder = new TOrder();
        buyoutOrder.setGoodsId(order.getGoodsId());
        buyoutOrder.setGsid(order.getGsid());
        buyoutOrder.setStoreid(order.getStoreid());
        buyoutOrder.setOrderType(2);
        buyoutOrder.setOrderPid(orderId);
        buyoutOrder.setDeposit(0.0);
        List<TOrderBill> bills = tOrderBillMapper.listCustomerBillByOrderId(orderId);
        double buyPriceAfterStore = serviceUtil.getBuyPriceAfterStore(bills, order.getBuyPrice());
        buyoutOrder.setRent(buyPriceAfterStore);
        buyoutOrder.setBuyPrice(order.getBuyPrice());
        buyoutOrder.setNum(order.getNum());
        buyoutOrder.setShippingFee(0.0);
        buyoutOrder.setOrderCode(CodeUtil.generateOrderCode());
        buyoutOrder.setBuyoutStatus(1);
        buyoutOrder.setCustomerid(serviceUtil.getCustomerId());
        buyoutOrder.setUsername(order.getUsername());
        buyoutOrder.setUserphone(order.getUserphone());
        buyoutOrder.setUserAddress(order.getUserAddress());
        buyoutOrder.setBuyPriceAfterStore(buyPriceAfterStore);
        buyoutOrder.setSettlementRatio(order.getSettlementRatio());
        buyoutOrder.setRenewalRate(order.getRenewalRate());
        buyoutOrder.setDepositStatus(1);
        buyoutOrder.setOrderStatus(4);
        buyoutOrder.setRentAfterCoupon(buyPriceAfterStore);
        buyoutOrder.setLeasePeriod(1);
        LocalDateTime beginTime = LocalDate.now().plusDays(1).atTime(00, 00, 00);
        LocalDateTime endtime = beginTime.plusDays(3).minusSeconds(1);
        buyoutOrder.setPlanBegin(beginTime);
        buyoutOrder.setPlanEnd(endtime);
        buyoutOrder.setRealBegin(beginTime);
        buyoutOrder.setRealEnd(endtime);
        buyoutOrder.setDay(3);
        orderMapper.insert(buyoutOrder);

        TOrderBill bill = new TOrderBill();
        bill.setOrderId(buyoutOrder.getOrderId());
        bill.setPeriod(1);
        bill.setOldPeriod(1);
        bill.setBillAmount(buyoutOrder.getRent());
        bill.setOldAmount(bill.getBillAmount());
        bill.setPayAmount(buyPriceAfterStore);
//        serviceUtil.setStoreAmount(bill);
        bill.setDepositPay(0.0);
        bill.setBillStatus(0);
        bill.setTransactionId(CodeUtil.generateBillSequence());
        bill.setBeginTime(beginTime);
        bill.setEndTime(endtime);
        bill.setPlanDate(beginTime.minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        serviceUtil.setStoreAmount(bill);
        bill.setStoreid(order.getStoreid());
        bill.setStageNo(1L);
        bill.setInstallmentNo(bill.getPeriod());
        tOrderBillMapper.insert(bill);
    }

    /**
     * @Description 我要续租
     * @Date 2024/8/30 23:45
     * @Author YWX
     * @Param [bill]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void renewLease(OrderBillEntity entity) {
        TOrderBill bill = TCustomerOrderService.convertToOrderBill(entity);

        Integer orderId = bill.getOrderId();
        TOrder tOrder = checkOrder(orderId);
        Integer orderStatus = tOrder.getOrderStatus();
        if (orderStatus.equals(6)) {
            throw new ServiceException("订单已完结，无法续租！");
        } else if (orderStatus.equals(7)) {
            throw new ServiceException("订单已取消，无法续租！");
        }
        bill.setBillStatus(0);
        bill.setStoreid(tOrder.getStoreid());
        List<TOrderBill> bills = serviceUtil.setBillPrice(bill, entity.getCouponid(), 1);
        tOrderBillMapper.insertBatchSomeColumn(bills);

        //更新续租状态
        TOrder order = new TOrder();
        order.setOrderId(orderId);
        order.setRenewStatus(1);
        order.setRealEnd(bills.get(bills.size() - 1).getEndTime());
        order.setLeasePeriod(tOrder.getLeasePeriod() + bills.size());
        order.setDay(ToolUtils.getDaysBetween(tOrder.getRealBegin(), bill.getEndTime()));
        orderMapper.updateRenewById(order);

        //记录日志
        TOrderLog orderLog = new TOrderLog();
        orderLog.setOrderCode(tOrder.getOrderCode());
        orderLog.setLogType("续租申请");
        orderLog.setComm("续租申请成功，续租金额：" + bill.getPayAmount());
        orderLogService.saveOrderLog(orderLog);
    }

    private static @NotNull TOrderBill convertToOrderBill(OrderBillEntity entity) {
        TOrderBill bill = new TOrderBill();
        bill.setOrderId(entity.getOrderId());
        bill.setEndTime(ToolUtils.getEndDateTime(entity.getEndTime()));
        return bill;
    }

    private TOrder checkOrder(Integer orderId) {
        // 通过id查询数据处理 详情
        TOrder originTOrder = orderMapper.selectById(orderId);
        if (originTOrder == null) {
            throw new ServiceException("未查询到对应的订单表信息！");
        }
        return originTOrder;
    }

    /**
     * @Description 订单详情
     * @Date 2024/9/4 22:45
     * @Author YWX
     * @Param [orderId]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> detailOrder(OrderBillEntity entity) {
        Map<String, Object> result = orderMapper.findByIdForCustomer(entity);
        Integer orderId = entity.getOrderId();
        if (!ToolUtils.isTrueInteger(orderId)) {
            orderId = ToolUtils.objToInteger(result.get("orderId"));
        }
        List<TOrderBill> bills = tOrderBillMapper.listCustomerBillByOrderId(orderId);
        result.put("bills", bills);
        setOrderBuyPriceAfterStore(result, bills);//到期买断价=签约价（买断价）-总租金
        return result;
    }

    /**
     * @Description 账单详情
     * @Date 2024/9/5 21:09
     * @Author YWX
     * @Param [orderId]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> detailOrderBill(OrderBillEntity entity) {
        Map<String, Object> result = orderMapper.findByIdForCustomer(entity);
        if (result == null) {
            throw new ServiceException("订单不存在！");
        }
        Integer orderId = entity.getOrderId();
        if (!ToolUtils.isTrueInteger(orderId)) {
            orderId = ToolUtils.objToInteger(result.get("orderId"));
        }
        List<TOrderBill> bills = tOrderBillMapper.listCustomerBillByOrderId(orderId);
        String orderType = ToolUtils.objToString(result.get("orderType"));
        String buyoutStatus = ToolUtils.objToString(result.get("buyoutStatus"));
        double payAmount = serviceUtil.getPayAmount(bills);
        if (orderType.equals("1") && !buyoutStatus.equals("2")) {//普通订单并且没有买断要重新计算买断价
            setOrderBuyPriceAfterStore(result, bills);//到期买断价=签约价（买断价）-总租金
        } else if (orderType.equals("2")) {
            List<TOrderBill> bills1 = tOrderBillMapper.listCustomerBillByOrderId(ToolUtils.objToInteger(result.get("orderPid")));
            double payRent = serviceUtil.getPayAmount(bills1);
            payAmount = ToolUtils.add(payAmount, payRent);
            TOrderBill bill = bills.get(0);
            result.put("couponPrice", ToolUtils.subtract(bill.getBillAmount(), bill.getPayAmount()));
        }
        double waitPay;
        if (orderType.equals("2")) {
            waitPay = ToolUtils.subtract(result.get("buyPrice"), payAmount);
        } else {
            waitPay = ToolUtils.subtract(result.get("rentAfterCoupon"), payAmount);
        }
        result.put("payAmount", payAmount);//已付金额
        result.put("waitPay", waitPay);//待付金额
        result.put("bills", bills);
        return result;
    }

    //到期买断价=签约价（买断价）-总租金
    private void setOrderBuyPriceAfterStore(Map<String, Object> result, List<TOrderBill> bills) {
        Double buyPrice = ToolUtils.objToDouble(result.get("buyPrice"));//原始买断价
        double billAmount = 0.0;
        double billAmount2 = serviceUtil.getPayAmount(bills);
        for (TOrderBill bill : bills) {
            Double amount = bill.getBillAmount();
            billAmount = ToolUtils.add(billAmount, amount);
        }
        result.put("buyPriceAfterStore", serviceUtil.getBuyPrice(buyPrice, billAmount2));//申请买断要支付的买断价
        result.put("buyPriceEndDate", serviceUtil.getBuyPrice(buyPrice, billAmount));//到期买断价
    }


    /**
     * @Description 获取续租实付金额
     * @Date 2024/9/7 16:19
     * @Author YWX
     * @Param [bill]
     * @Return java.lang.Object
     **/
    public Object getRenewLeasePrice(OrderBillEntity entity) {
        TOrderBill bill = TCustomerOrderService.convertToOrderBill(entity);
        serviceUtil.setBillPrice(bill, entity.getCouponid(), 0);
        return bill.getPayAmount();
    }

    /**
     * @Description 归还
     * @Date 2024/9/19 12:44
     * @Author YWX
     * @Param [orderDelivery]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void sendBack(TOrderDelivery orderDelivery) {
        orderDelivery.setType(2);
        orderDelivery.setDispatchTime(LocalDateTime.now());
        orderDeliveryMapper.insert(orderDelivery);
        orderMapper.updateOrderStatusByCode(orderDelivery.getOrderCode(), 5);//更改订单状态为归还中
    }

    /**
     * @Description 获取订单押金支付状态
     * @Date 2024/9/21 16:07
     * @Author YWX
     * @Param [orderId]
     * @Return java.lang.Integer
     **/
    public Integer getDepositStatus(Integer orderId) {
        return orderMapper.getDepositStatus(orderId);
    }

    /**
     * @Description 物流信息
     * @Date 2024/9/21 16:36
     * @Author YWX
     * @Param [orderCode, type]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> detailDelivery(String orderCode, Integer type) {
        return serviceUtil.detailDelivery(orderCode, type);
    }

    /**
     * @Description 取消订单
     * @Date 2024/9/24 22:14
     * @Author YWX
     * @Param [orderId]
     * @Return void
     **/
    public void orderCancel(Integer orderId) {
        Integer customerId = serviceUtil.getCustomerId();
        String userName = "客户";
        serviceUtil.orderCancel(orderId, customerId, userName, 0);
    }

    /**
     * @Description 获取身份认证地址
     * @Date 2024/9/25 23:13
     * @Author YWX
     * @Param [orderCode]
     * @Return java.util.Map<java.lang.String, java.lang.String>
     **/
    public Map<String, String> getCertifyUrl(Integer orderId) {
        Map<String, String> result = new HashMap<>();
        TOrder tOrder = orderMapper.selectById(orderId);
        if (tOrder == null) {
            throw new ServiceException("订单不存在！");
        }
        TCustomer customer = serviceUtil.getCustomerById(tOrder.getCustomerid());
        String certifyId = AlipayCreate.alipayUserCertifyOpenInitialize(customer.getRealName(), customer.getIdNumber());
        String certifyUrl = AlipayCreate.alipayUserCertifyOpenCertify(certifyId);
        TOrder order = new TOrder();
        order.setOrderId(tOrder.getOrderId());
        order.setCertifyId(certifyId);
        order.setCertifyUrl(certifyUrl);
        orderMapper.updateById(order);
        result.put("certifyUrl", certifyUrl);
        result.put("certifyId", certifyId);
        return result;
    }

    /**
     * @Description 根据姓名身份证号获取身份认证地址
     * @Date 2024/9/27 22:00
     * @Author YWX
     * @Param [customer]
     * @Return java.util.Map<java.lang.String, java.lang.String>
     **/
    public Map<String, String> getCertifyUrl2(TCustomerAuth auth) {
        Map<String, String> result = new HashMap<>();
        String certifyId = "";
        String certifyUrl = "";
        TOrder certifyOrder = orderMapper.getCertifyByIdOrCode(auth);
        if (certifyOrder == null) {
            throw new ServiceException("订单不存在！");
        }
        try {
            certifyId = AlipayCreate.alipayUserCertifyOpenInitialize(auth.getInRealName(), auth.getInIdNumber());
            certifyUrl = AlipayCreate.alipayUserCertifyOpenCertify(certifyId);
            TOrder order = new TOrder();
            order.setOrderId(auth.getOrderId());
            order.setCertifyId(certifyId);
            order.setCertifyUrl(certifyUrl);
            order.setOrderCode(auth.getOrderCode());
            orderMapper.updateCertify(order);
            serviceUtil.updateCustomerAuth(auth.getInRealName(), auth.getInIdNumber());//保存客户输入认证信息
        } catch (Exception e) {
            if (e.getMessage().contains("接口调用权限不足")) {
                String errorMsg = "接口调用权限不足";
                checkCertify(0, certifyOrder, errorMsg, certifyOrder.getCustomerid());
            } else {
                throw new RuntimeException(e);
            }
        }
        result.put("certifyUrl", certifyUrl);
        result.put("certifyId", certifyId);
        return result;
    }

    /**
     * @Description 查询身份认证结果
     * @Date 2024/9/25 22:37
     * @Author YWX
     * @Param [certifyId]
     * @Return java.lang.Integer
     **/
    @Transactional(rollbackFor = Exception.class)
    public Integer getCertifyResult(String certifyId) {
        TOrder order = orderMapper.selectByCertifyId(certifyId);
        if (order == null) {
            throw new ServiceException("认证订单不存在！");
        }
        Integer certifyPassed = null;
        Integer customerid = order.getCustomerid();

        String errorMsg = "";
        try {
            certifyPassed = AlipayCreate.alipayUserCertifyOpenQuery(certifyId);
        } catch (Exception e) {
            if (e.getMessage().contains("接口调用权限不足")) {
                errorMsg = "接口调用权限不足";
            } else {
                throw new RuntimeException(e);
            }
        }
        return checkCertify(certifyPassed, order, errorMsg, customerid);
    }

    //校验身份认证结果
    private int checkCertify(Integer certifyPassed, TOrder order, String errorMsg, Integer customerid) {
        Map<String, Object> auth = serviceUtil.findCustomerAuthByCustomerId(customerid);
        if (errorMsg.equals("接口调用权限不足")) {
            if (auth != null && auth.get("inCustomerAuth").equals(1)) {
                certifyPassed = 1;
            } else {
                certifyPassed = 2;
            }
        }
        if (!certifyPassed.equals(order.getCertifyPassed())) {
            order.setCertifyPassed(certifyPassed);
            orderMapper.updateById(order);
        }
        if (certifyPassed.equals(1)) {
            if (auth != null && ToolUtils.isNotEmpty(auth.get("inIdNumber")) && auth.get("inCustomerAuth").equals(0)) {
                serviceUtil.updateCustomerAuthById(ToolUtils.objToInteger(auth.get("caid")), 1);//更新客户输入认证状态
                serviceUtil.updateCustomerIdNumberById(customerid, ToolUtils.objToString(auth.get("inRealName")), ToolUtils.objToString(auth.get("inIdNumber")));//更新客户身份证信息
            }
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            RequestContextHolder.setRequestAttributes(requestAttributes, true);//设置子线程共享
            Integer num = serviceUtil.getContractNumByOrderId(order.getOrderId());
            if (num.compareTo(1) < 0) {//没有生成合同
                List<TOrderBill> bills = tOrderBillMapper.listCustomerBillByOrderId(order.getOrderId());
                String goodsName = goodsMapper.getNameById(order.getGoodsId());
                String specsName = goodsSpecsMapper.getNameById(order.getGsid());
                TCustomer tCustomer = serviceUtil.getAuthByCustomerId(order.getCustomerid());//设置订单风控报告
                serviceUtil.saveOrderContract(order, bills, goodsName, specsName, tCustomer, 1, requestAttributes);
            }
        }
        return certifyPassed;
    }

    /**
     * @Description 获取订单认证信息
     * @Date 2024/9/25 23:33
     * @Author YWX
     * @Param [orderId]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> getOrderAuth(OrderBillEntity entity) {
        return orderMapper.getOrderAuth(entity);
    }

    /**
     * @Description 获取订单服务信息
     * @Date 2024/9/27 13:07
     * @Author YWX
     * @Param [orderId]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> getOrderService(Integer orderId) {
        return orderMapper.getOrderService(orderId);
    }

    /**
     * @Description 获取商家服务信息
     * @Date 2024/11/9 22:26
     * @Author YWX
     * @Param [storeid]
     * @Return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> getStoreService(Integer storeid) {
        return orderMapper.getStoreService(storeid);
    }

    /**
     * @Description 订单协议列表
     * @Date 2024/10/4 23:12
     * @Author YWX
     * @Param [orderId]
     * @Return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     **/
    public List<Map<String, Object>> listContract(Integer orderId) {
        return orderContractMapper.listContract(orderId);
    }

    /**
     * @Description 申请取消订单
     * @Date 2024/10/9 22:40
     * @Author YWX
     * @Param [order]
     * @Return void
     **/
    public void applyForCancel(TOrder order) {
        TOrder tOrder = orderMapper.selectByOrderCode(order.getOrderCode());
        if (tOrder == null) {
            throw new ServiceException("订单不存在！");
        } else if (tOrder.getOrderStatus().equals(7)) {
            throw new ServiceException("订单已取消！");
        } else if (!tOrder.getCancelCheckStatus().equals(0)) {
            throw new ServiceException("您已经申请过取消订单，请勿重复申请！");
        }
        Integer orderId = tOrder.getOrderId();
        order.setOrderId(orderId);
        order.setCancelTime(LocalDateTime.now());
        order.setCancelStatus(1);
        orderMapper.updateById(order);

        //记录日志
        TOrderLog orderLog = new TOrderLog();
        orderLog.setOrderCode(order.getOrderCode());
        orderLog.setLogType("申请取消订单");
        String cause = getCause(order.getCancelCause());//获取取消原因
        String comm = "客户申请取消订单,原因：" + cause;
        String cancelComm = order.getCancelComm();
        if (ToolUtils.isNotEmpty(cancelComm)) {
            comm += ",备注：" + cancelComm;
        }
        orderLog.setComm(comm);
        orderLogService.saveOrderLog(orderLog);
    }

    //获取取消原因（10押金问题 20租金问题 30多拍/错拍 40收货信息有误 50商品问题 60审核流程/时长问题 70发货问题 80商家问题 90我不想要了 100计划有变 110其他）
    private String getCause(Integer cancelCause) {
        String cause = "";
        if (cancelCause.equals(10)) {
            cause = "押金问题";
        } else if (cancelCause.equals(20)) {
            cause = "租金问题";
        } else if (cancelCause.equals(30)) {
            cause = "多拍/错拍";
        } else if (cancelCause.equals(40)) {
            cause = "收货信息有误";
        } else if (cancelCause.equals(50)) {
            cause = "商品问题";
        } else if (cancelCause.equals(60)) {
            cause = "审核流程/时长问题";
        } else if (cancelCause.equals(70)) {
            cause = "发货问题";
        } else if (cancelCause.equals(80)) {
            cause = "商家问题";
        } else if (cancelCause.equals(90)) {
            cause = "我不想要了";
        } else if (cancelCause.equals(100)) {
            cause = "计划有变";
        } else if (cancelCause.equals(110)) {
            cause = "其他";
        }
        return cause;
    }

    /**
     * @Description 获取账单支付信息
     * @Date 2024/10/12 12:59
     * @Author YWX
     * @Param [bill]
     * @Return cn.psvmc.cxzapi.model.order.TOrderBill
     **/
    public TOrderBill getBillPay(TOrderBill bill) {
        rwLock.readLock().lock();
        TOrderBill orderBill;
        try {
            orderBill = tOrderBillMapper.selectById(bill.getObid());
            if (orderBill == null) {
                throw new ServiceException("账单不存在！");
            }
        } finally {
            rwLock.readLock().unlock();
        }

        rwLock.writeLock().lock();
        try {
            Integer billStatus = orderBill.getBillStatus();
            if (orderBill.getPayAmount().compareTo(0.0) <= 0) {
                orderBill.setBillStatus(1);
                orderBill.setTradeStatus(1);
                LocalDateTime payTime = LocalDateTime.now();
                orderBill.setPayTime(payTime);
                orderBill.setCutTime(payTime);
                orderBill.setRealDate(payTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                orderBill.setAvailableAmount(0.0);
                tOrderBillMapper.updateById(orderBill);
            } else if (orderBill.getIsGenerate().equals(0)) {
                String tradeNo = getTradeNo(orderBill);
                bill.setTradeNo(tradeNo);
                bill.setIsGenerate(1);
                bill.setInstallmentOrderId(orderBill.getInstallmentOrderId());
                tOrderBillMapper.updateById(bill);
                orderBill.setTradeNo(tradeNo);
                orderBill.setIsGenerate(1);
            } else if (billStatus.equals(0) || billStatus.equals(3)) {//交易号已生成，未支付先查询交易状态，如果已支付，则更新账单状态
                AlipayTradeQueryResponse response = AlipayCreate.alipayTradeQuery(orderBill.getTransactionId(), orderBill.getTradeNo());
                String tradeStatus = response.getTradeStatus();
                if (response.isSuccess() && tradeStatus.equals("TRADE_SUCCESS")) {
                    orderBill.setBillStatus(1);
                    orderBill.setTradeStatus(1);
                    Date sendPayDate = response.getSendPayDate();
                    LocalDateTime payTime = ToolUtils.dateToLocalDateTime(sendPayDate);
                    orderBill.setRealDate(payTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                    orderBill.setPayTime(payTime);
                    tOrderBillMapper.updateBillStatus(orderBill);
                } else if (tradeStatus.equals("TRADE_CLOSED") || "交易不存在".equals(response.getSubMsg())) {
                    if (!billStatus.equals(3)) {
                        orderBill.setTradeStatus(3);
                        tOrderBillMapper.updateTradeStatus(orderBill);
                    }
                    TOrderBill newBill = tOrderBillMapper.getByOrderIdAndPeriod(orderBill.getOrderId(), orderBill.getPeriod());
                    if (newBill == null) {
                        orderBill.setObid(null);
                        orderBill.setTransactionId(CodeUtil.generateBillSequence());
                        orderBill.setIsGenerate(1);
                        orderBill.setBillStatus(0);
                        orderBill.setTradeStatus(0);
                        orderBill.setTradeNo(getTradeNo(orderBill));
                        orderBill.setPayType(0);
                        orderBill.setRealDate(null);
                        orderBill.setPayTime(null);
                        orderBill.setCutTime(null);
                        orderBill.setNum(0);
                        tOrderBillMapper.insert(orderBill);
                    } else {
                        if (newBill.getBillStatus().equals(0) && newBill.getIsGenerate().equals(0)) {
                            String tradeNo = getTradeNo(orderBill);
                            newBill.setInstallmentOrderId(orderBill.getInstallmentOrderId());
                            newBill.setTradeNo(tradeNo);
                            newBill.setIsGenerate(1);
                            tOrderBillMapper.updateById(newBill);
                        }
                        orderBill = newBill;
                    }
                }
            }
        } finally {
            rwLock.writeLock().unlock();
        }
        return orderBill;
    }

    //获取支付宝交易号
    private String getTradeNo(TOrderBill orderBill) {
        TOrder tOrder = orderMapper.getRestAmountByOrderId(orderBill.getOrderId());
        if (tOrder.getOrderType().equals(2) && tOrder.getBuyoutStatus().equals(1)) {
            throw new ServiceException("请审核通过后在支付！");
        }
        orderBill.setOrderCode(tOrder.getOrderCode());
        String openid = customerMapper.getOpenIdByCustomerId(tOrder.getCustomerid());
        String type = ToolUtils.getTypeByOrderType(tOrder.getOrderType());
        String installmentOrderId = null;
        if (tOrder.getConfirmed().equals(1)) {
            AlipayOpenMiniOrderInstallmentCreateResponse createResponse = AlipayCreate.orderInstallmentCreate(orderBill, openid, type, true);
            installmentOrderId = createResponse.getInstallmentOrderId();
        }
        orderBill.setInstallmentOrderId(installmentOrderId);
        GoodsDetail gd = orderMapper.getGoodsDetail(orderBill.getOrderId());
        String goodsName = gd.getGoodsName();//根据订单ID获取商品名称
        String body = "商家：" + serviceUtil.getStoreName(tOrder.getStoreid()) + "；订单号：" + tOrder.getOrderCode();
        return serviceUtil.getTradeNo(orderBill.getTransactionId(), orderBill.getPayAmount(), goodsName + "-第" + orderBill.getPeriod() + "期", body, openid, gd);
    }

    /**
     * @Description 归还详情
     * @Date 2024/10/22 23:08
     * @Author YWX
     * @Param [orderCode]
     * @Return java.util.Map
     **/
    public Map detailReturn(String orderCode) {
        return orderMapper.detailReturn(orderCode);
    }

    /**
     * @Description 确认收货
     * @Date 2024/10/25 17:03
     * @Author YWX
     * @Param [orderCode]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void confirmReceipt(String orderCode) {
        TOrder order = orderMapper.selectByOrderCode(orderCode);
        //已收货的不在处理
        if (order.getOrderStatus().compareTo(4) > 0) {
            return;
        }
        TOrder order2 = new TOrder();
        order2.setOrderId(order.getOrderId());
        order2.setOrderStatus(4);
        orderMapper.updateById(order2);

        //添加操作日志
        TOrderLog log = new TOrderLog();
        log.setOrderCode(order.getOrderCode());
        log.setLogType("确认收货");
        log.setComm("客户" + "确认收货");
        orderLogService.saveOrderLog(log);
    }

    /**
     * @Description 获取订单状态数量
     * @Date 2024/10/28 23:48
     * @Author YWX
     * @Param []
     * @Return java.util.Map
     **/
    public Map getStatusNum() {
        Integer customerId = serviceUtil.getCustomerId();
        return orderMapper.getMyStatusNum(customerId);
    }

    /**
     * @Description 快捷下单成功详情
     * @Date 2025/1/16 22:41
     * @Author YWX
     * @Param [orderCode]
     * @Return java.util.Map
     **/
    public Map detailOrderByCode(String orderCode) {
        Map<String, Object> result = orderMapper.detailOrderByCode(orderCode);
        result.put("buyPriceEndDate", serviceUtil.getBuyPrice(ToolUtils.objToDouble(result.get("buyPrice")), ToolUtils.objToDouble(result.get("rentAfterCoupon"))));
        return result;
    }
}
